package management

import (
	"bytes"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/gorilla/mux"
	"github.com/gorilla/sessions"
	"github.com/jsrccb/nachuan/common"
)

// http接口

type ApiServer struct {
	httpServer *http.Server
}

var (
	G_apiServer  *ApiServer
	templates    *template.Template
	sessionStore = sessions.NewCookieStore([]byte(common.SESSIONKEY))
)

func NewAPIMux() *mux.Router {

	r := mux.NewRouter()
	s := r.PathPrefix("/api").Subrouter()
	initUploadFileApi(s)
	initUserApi(s)
	initRoleLimitsApi(s)
	initClueApi(s)
	initClueTraceApi(s)
	initSaleChannelApi(s)
	initRoleApi(s)
	initDepartmentApi(s)
	initOrderApi(s)
	initCustomMgrApi(s)
	initCollMgrApi(s)
	initCostMgrApi(s)
	initCustomTraceApi(s)
	initComplainMgrApi(s)

	r.Use(SessionMiddleware)
	r.PathPrefix("/uploadfile").Handler(http.StripPrefix("/uploadfile", http.FileServer(http.Dir(G_config.UploadFile))))
	
	r.PathPrefix("/downloadfile").Handler(http.StripPrefix("/downloadfile", http.FileServer(http.Dir(G_config.DownloadFile))))

	r.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir(G_config.WebRoot))))

	return r
}

func SessionMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		token := r.Header.Get("username")

		body, _ := ioutil.ReadAll(r.Body)

		//go的req读取后要重新生产body
		resbody := ioutil.NopCloser(bytes.NewReader(body))
		r.Body = resbody

		// fmt.Println(token, r.RequestURI, string(body))

		if r.RequestURI == "/api/user/signin" || r.RequestURI == "/api/user/signout" || r.RequestURI == "/api/user/useraddonce" {
			next.ServeHTTP(w, r)
			return
		}

		if r.RequestURI == "/filetest.html" || strings.HasPrefix(r.RequestURI, "/api/upload/") || strings.HasPrefix(r.RequestURI, "/uploadfile/") || strings.HasPrefix(r.RequestURI, "/downloadfile/") {
			next.ServeHTTP(w, r)
			return
		}

		if session, errret := sessionStore.Get(r, common.SESSIONUSER); errret != nil {
			if bytes, err := common.BuildResponse(-1, "error", "禁止登陆"); err == nil {
				w.Write(bytes)
			}
		} else {
			// fmt.Println(session.Values)
			phoneno := session.Values["username"]
			if token == phoneno {
				next.ServeHTTP(w, r)
			} else {
				if bytes, err := common.BuildResponse(-2, "error", "用户登陆超时，请重新登陆"); err == nil {
					w.Write(bytes)
				}
			}

		}
	},
	)

}

func startHttp() {

	srv := &http.Server{
		Handler: NewAPIMux(),
		Addr:    "0.0.0.0:" + strconv.Itoa(G_config.ApiPort),
		// Good practice: enforce timeouts for servers you create!
		ReadHeaderTimeout: time.Duration(G_config.ApiReadTimeout) * time.Millisecond,
		WriteTimeout:      time.Duration(G_config.ApiWriteTimeout) * time.Millisecond,
	}

	if err := srv.ListenAndServe(); err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

func InitApiserver() (err error) {
	go startHttp()
	return
}
